﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;

namespace Bookkeeping.Core.Infrastructure.Reflection
{
    public class PropertyReader<T>
    {
        MemberExpression _memberExpression;
        PropertyInfo _propertyInfo;

        public PropertyReader(Expression<Func<T, object>> expression)
        {

            TryReadMemberExpression(expression);

            if (!IsMemberExpressionInitialized)
                throw new ApplicationException("Could not read member expression. Use something like 'o => o.Title'");

            _propertyInfo = (PropertyInfo)_memberExpression.Member;
        }

        void TryReadMemberExpression(Expression<Func<T, object>> expression)
        {
            // Conversion from the actual property type to object
            if (expression.Body.NodeType == ExpressionType.Convert)
            {
                var castExpression = (UnaryExpression)expression.Body;
                _memberExpression = castExpression.Operand as MemberExpression;
            }
            else if (expression.Body.NodeType == ExpressionType.MemberAccess)
            {
                _memberExpression = expression.Body as MemberExpression;
            }
        }

        public bool IsMemberExpressionInitialized
        {
            get
            {
                return _memberExpression != null;
            }
        }

        public string PropertyName
        {
            get
            {
                return _propertyInfo.Name;
            }
        }
    }
}
